package com.ytrsoft.ui;

import cn.hutool.core.collection.CollUtil;
import com.ytrsoft.base.JSelect;
import com.ytrsoft.entity.*;
import com.ytrsoft.util.Request;

import javax.swing.*;
import java.awt.*;
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Stream;

public class LeftPane extends JPanel {

    private Model model;
    private Model modelV2;
    private JPanel mainPanel;
    private GridBagConstraints gbc;
    private JTextField keywordField;
    private JSelect rhymeSelect;
    private JSelect styleSelect;
    private JSelect moodSelect;
    private Submit submit;
    private final int H = 32;
    private final int W = 400;

    public interface Submit {
        void onSubmit(Params params);
    }

    public LeftPane() {
        setPreferredSize(new Dimension(W, getHeight()));
        setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
        List<Model> models = Request.fetchModels();
        if (CollUtil.isNotEmpty(models)) {
            model = models.get(0);
        }
        List<Model> modelsV2 = Request.fetchV2Models();
        if (CollUtil.isNotEmpty(modelsV2)) {
            modelsV2.forEach(m -> {
                if (m.getId() == 2) {
                    modelV2 = m;
                }
            });
        }
        buildUI();
        add(mainPanel);
    }

    public void setOnSubmit(Submit submit) {
        this.submit = submit;
    }

    private void buildUI() {
        mainPanel = new JPanel(new GridBagLayout());
        gbc = new GridBagConstraints();
        gbc.insets = new Insets(5, 5, 5, 5);
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.anchor = GridBagConstraints.WEST;

        keywordField = new JTextField();
        addItem(0, "参考词句", keywordField);

        styleSelect = new JSelect(getStyleOptions());
        addItem(1, "歌词风格", styleSelect);

        moodSelect = new JSelect(getMoodOptions());
        addItem(2, "歌词情绪", moodSelect);

        rhymeSelect = new JSelect(getRhymeOptions());
        addItem(3, "歌词韵脚", rhymeSelect);

        JButton generateBtn = new JButton("寻找灵感");
        generateBtn.setPreferredSize(new Dimension(W - 100, H));
        generateBtn.addActionListener(e -> handleSubmit());
        addItem(4, null, generateBtn);
    }

    private void addItem(int row, String label, Component component) {
        gbc.gridx = 0;
        gbc.gridy = row;
        if (label != null) {
            mainPanel.add(new JLabel(label), gbc);
            component.setPreferredSize(new Dimension(W - 100, H));
        }
        gbc.gridx = 1;
        mainPanel.add(component, gbc);
    }

    private Option[] getStyleOptions() {
        return extractOptions(model, Model::getStyles, Style::getValue, Style::getId);
    }

    private Option[] getRhymeOptions() {
        return extractOptions(model, Model::getRhymes, Rhyme::getValue, Rhyme::getId);
    }

    private Option[] getMoodOptions() {
        Stream<Option> defaults = Stream.of(new Option("不设限", 0));
        Option[] options = extractOptions(modelV2, Model::getMoods, Mood::getValue, Mood::getId);
        Stream<Option> moods = Arrays.stream(options);
        return Stream.concat(defaults, moods).toArray(Option[]::new);
    }

    private <M, T> Option[] extractOptions(M model, Function<M, List<T>> extractor, Function<T, String> valueMapper, Function<T, Integer> idMapper) {
        return extractor.apply(model).stream()
                .map(item -> new Option(valueMapper.apply(item), idMapper.apply(item)))
                .toArray(Option[]::new);
    }

    private void handleSubmit() {
        Params params = new Params();
        params.setInput(keywordField.getText());
        Option style = (Option) styleSelect.getSelectedItem();
        if (style != null) {
            params.setStyle(style.getValue());
        }
        Option rhyme = (Option) rhymeSelect.getSelectedItem();
        if (rhyme != null) {
            params.setRhyme(rhyme.getValue());
        }
        Option mood = (Option) moodSelect.getSelectedItem();
        if (mood != null) {
            params.setMood(mood.getValue());
        }
        if (submit != null) {
            submit.onSubmit(params);
        }
    }
}
